package org.ljy.forum6.services.impl;

import lombok.extern.slf4j.Slf4j;
import org.ljy.forum6.common.AppResult;
import org.ljy.forum6.common.ResultCode;
import org.ljy.forum6.dao.UserMapper;
import org.ljy.forum6.exception.ApplicationException;
import org.ljy.forum6.model.User;
import org.ljy.forum6.services.IUserService;
import org.ljy.forum6.utils.MD5Util;
import org.ljy.forum6.utils.StringUtil;
import org.ljy.forum6.utils.UUIDUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;


@Slf4j
@Service
public class UserServiceImpl implements IUserService {


    @Resource
    private UserMapper userMapper;
    /**
     * 用户注册
     * @param user
     */
    @Override
    public void createNormalUser(User user) {
        log.info("用户注册Service");
        //参数已经在controller层校验完成
        //1.检测用户是否已经存在
        User newUser = userMapper.selectByUserName(user.getUsername());
        if(newUser != null) {
            //用户已存在，抛出异常
            log.error("用户已存在");
            throw new ApplicationException(AppResult.failed(ResultCode.AILED_USER_EXISTS));
        }
        //2.给对象设置初始值
        user.setGender((byte) 2);//性别默认保密
        user.setIsAdmin((byte) 0);//默认非管理员
        user.setArticleCount(0);//默认文章数量为0
        user.setState((byte) 0);//用户默认正常
        user.setDeleteState((byte) 0);
        //设置注册和修改时间
        Date now = new Date();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        //3.开始注册(插入)
        Integer row = userMapper.insert(user);
        if(row != 1) {
            log.error("插入失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        log.info("新增用户成功");
    }

    /**
     * 根据用户名字查询用户
     * @param username 用户名字
     * @return
     */
    @Override
    public User selectByUserName(String username) {
        User user = userMapper.selectByUserName(username);
        if(user == null) {
            log.error(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        return user;
    }

    /**
     * 用户登陆
     * @param username 用户名字
     * @param password 用户密码
     * @return
     */
    @Override
    public User login(String username, String password) {
        //1.查询用户
        User user = selectByUserName(username);
        //2.校验密码
        String salt = user.getSalt();
        String encryPassword = MD5Util.madSalt(password,salt);
        if(!encryPassword.equals(user.getPassword())) {
            log.error(ResultCode.FAILED_LOGIN.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        //3.返回正确用户
        return user;
    }

    /**
     * 根据用户id查询用户信息
     * @param id 用户id（主键）
     * @return
     */
    @Override
    public User selectById(Long id) {
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        return user;
    }


    /**
     * 作者文章数+1 (发布文章)
     */
    @Override
    public void addOneArticleCountById(Long id) {
        //1.参数验证
        if(id<=0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //2.根据id查询该作者
        User user = userMapper.selectByPrimaryKey(id);
        if(user==null) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //3.创建新对象进行修改
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount()+1);
        //4.调用dao层
        userMapper.updateByPrimaryKeySelective(updateUser);
    }

    /**
     * 删除帖子--对应作者的文章数-1
     */
    @Override
    public void subOneArticleCountById(Long id) {
        //1.参数校验
        if(id==null || id<=0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //2.查询用户是否存在
        User user = userMapper.selectByPrimaryKey(id);
        if(user==null || user.getDeleteState()==1) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //3.判断用户文章数量是否合法
        if(user.getArticleCount()<=0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //4.更新用户文章数量
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount()-1);
        //5.调用dao
        int row  = userMapper.updateByPrimaryKeySelective(updateUser);
        if( row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
    }

    /**
     * 修个个人信息（不包括头像和密码）
     */
    @Override
    public void modifyInfo(User user) {
        //用户名、性别、昵称、个人邮箱、电话号码、个人简介

        //1.参数校验
        if(user == null || user.getId() == null || user.getId() <= 0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //2.检验用户是否存在
        User exitUser = userMapper.selectByPrimaryKey(user.getId());
        if(exitUser == null) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //3.定义一个标志位，如果标志位被修改了就说明有值需要被修改
        Boolean check = false;
        //4.定义一个更新对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        //5.校验用户名--校验修改后的用户名和数据库中的用户名是否相同
        if(!StringUtil.isEmpty(user.getUsername()) && !user.getUsername().equals(exitUser.getUsername())) {
            User checkUser = userMapper.selectByUserName(user.getUsername());
            if(checkUser != null) {
                log.warn("需要修改成的用户名已经存在");
                throw new ApplicationException(AppResult.failed("需要修改成的用户名已经存在"));
            }
            updateUser.setUsername(user.getUsername());
            check = true;
        }
        //6.校验昵称
        if(!StringUtil.isEmpty(user.getNickname() ) && !user.getNickname().equals(exitUser.getNickname())) {
            updateUser.setNickname(user.getNickname());
            check = true;
        }
        //7.校验性别
        if(user.getGender() != null && user.getGender() != exitUser.getGender()) {
            updateUser.setGender(user.getGender());
            if (updateUser.getGender() > 2 || updateUser.getGender() < 0) {
                updateUser.setGender((byte) 2);
            }
            check = true;
        }
        //8.校验邮箱
        if(user.getEmail() != null && user.getEmail() != exitUser.getEmail()) {
            updateUser.setEmail(user.getEmail());
            check = true;
        }
        //9.校验电话号码
        if(!StringUtil.isEmpty(user.getPhoneNum() ) && !user.getPhoneNum().equals(exitUser.getPhoneNum())) {
            updateUser.setPhoneNum(user.getPhoneNum());
            check = true;
        }
        //10.校验个人简介
        if(!StringUtil.isEmpty(user.getRemark() ) && !user.getRemark().equals(exitUser.getRemark())) {
            updateUser.setRemark(user.getRemark());
            check = true;
        }
        //11.校验标志位
        if(!check) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //12.调用dao
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
    }

    /**
     * 修改密码
     * @param id 用户Id
     * @param newPassword 用户新改的密码
     * @param oldPassword 用户原始密码
     */
    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
        //1.校验用户是否存在
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null || user.getDeleteState() == 1 || user.getState()==1) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //2.验证原始密码是否正确(重新加密再对比验证)
        String oldSalt = user.getSalt();
        String oldEncryptPassword = MD5Util.madSalt(oldPassword,oldSalt);
        if( !oldEncryptPassword.equals(user.getPassword())) {
            log.warn("原始密码不正确");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //3.构造新的密码
        String salt = UUIDUtil.UUID_32();
        String encryptPassword = MD5Util.madSalt(newPassword,salt);
        //4.验证原始密码和新密码是否相同
        if(encryptPassword.equals(oldPassword)) {
            log.warn("原始密码和新密码相同");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //5.构造新对象
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setPassword(encryptPassword);
        updateUser.setSalt(salt);
        //6.调用dao
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }

    }
}
